package com.wandian.texas;

import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.PriorityBlockingQueue;
import java.util.concurrent.TimeUnit;
import com.wandian.command.Command;
import com.wandian.command.CommandSet;
import com.wandian.executor.TimerCommand;
import com.wandian.util.ArrayList;
import com.wandian.util.ConsoleTable;
import com.wandian.util.DateUtil;
import com.wandian.util.Log;
import com.wandian.util.TimeWatch;

/**
 * @author long
 * @date 2012-10-01 下午1:04:08
 * @qq 108232706
 * @description ThreadPool
 */
public class ThreadPool {

	/*
	 * // 空闲命令资源 private ArrayList<BaseCommandObject> freeList = null; //
	 * 正在执行的命令资源 private ArrayList<BaseCommandObject> useList = null;
	 */
	// 命令线程数组
	private ArrayList<CmdThread> cmdThreaLlist = null;
	public static final Map<Short, Exception> ErrorCmdMap = new ConcurrentHashMap<Short, Exception>();
	private ArrayBlockingQueue<CmdThread> idleThreads = null;
	// private ArrayBlockingQueue<CmdThread> busyThreads=null;
	private boolean isThreadPoolStated;
	private boolean isInit;// 是否初始化，如线程，队列,数组，commandmap,
	private static ThreadPool instance = null;
	// private final boolean isinitFreeList = false;// 是否初始化命令资源列表
	// private boolean isinitCommand = false;// 是否初始化命令列表
	// 负责执行命令的线程空闲，表明可以调度唤醒
	private final short idle_status = 0;
	// 负责执行命令的线程正在执行命令，表明忙
	private final short ready_exec_status = 1;
	private final short ready_pause_status = 2;
	private Thread dispatchProcessThread;
	private Thread dispatchTimerProcessThread;
	private short dispatchStatus = 0;// 派发任务状态
	private boolean runDispatchProcess;
	private final TimeWatch timeWatch;// 计时器
	private final TimeWatch timerTimeWatch;// 计时器
	// dbMgr[]
//	private final boolean printDetail = true;
	private PriorityBlockingQueue<BaseCommandObject> timerworkQueue = null;// 具有时间周期性概念的命令
	private ArrayBlockingQueue<BaseCommandObject> workQueue = null;// 具有时间周期性概念的命令
	private ArrayBlockingQueue<BaseCommandObject> freeQueue = null;// 资源数
	private SessionMgr sessionMgr;

	public BaseCommandObject sessionMgrCommand() {
		return this.sessionMgr.command;
	}

	// private static AtomicLong currentCommandSize;//当前队列中命令

	public ThreadPool(Single single) {
		if (single == null) {
			throw new IllegalArgumentException("Can\'t create instance ThreadPool , Single is Null!");
		}
		timeWatch = new TimeWatch("ThreadPool_dispatchProcessThread");
		timeWatch.isTimerFormat = true;
		timerTimeWatch = new TimeWatch("ThreadPool_dispatchTimerProcessThread");
		timerTimeWatch.isTimerFormat = true;
	}

	/**
	 * 采用单例模式，保证线程池在全局唯一
	 * 
	 * @return
	 */
	public static ThreadPool getInstance() {
		if (instance == null) {
			syncInit();
		}
		return instance;
	}

	private static synchronized void syncInit() {
		if (instance == null) {
			instance = new ThreadPool(new Single());
		}
	}

	/**
	 * 加载系统需要执行的命令实例
	 * 
	 * @param initResult
	 * @param componentName
	 * @return
	 */
	public boolean initComponent(boolean initResult, String componentName) {
		if (!initResult) {
			Log.error(componentName + "错误");
		} else {
			Log.info(componentName + "加载完成");
		}
		return initResult;
	}

	/**
	 * 加载系统需要执行的命令实例到Map集合
	 * 
	 * @return
	 */
	private boolean initCommand() {
		return initComponent(CommandSet.load(), "命令加载");
	}

	/**
	 * 启动m线程池，n个资源列表，初始化命令
	 * 
	 * @param threadnum
	 *            处理命令的线程池大小
	 * @param buffernum
	 *            命令队列的长度
	 * @return
	 * @throws Throwable
	 */
	public boolean Start(SessionMgr _sessionMgr, int threadnum, int cmdQueueMaxCount) throws Throwable {
		if (!isThreadPoolStated) {
			if (!isInit) {
				if (!init(threadnum, cmdQueueMaxCount)) {
					return false;
				}
			}
			this.isThreadPoolStated = true;
			dispatchStatus = 0;
		}
		this.sessionMgr = _sessionMgr;
		return true;
	}

	private boolean init(int threadnum, int cmdQueueMaxCount) throws Throwable {
		// 初始化命令
		if (!initCommand()) {
			return false;
		}
		// 初始化数据库连接池
//		DaoManager.init(threadnum + 1);// 主线程预备一个
		// 初始化线程
		createthread(threadnum);
		// 初始化资源,不需要初始化命令列表，因为命令处理完就消失，而且是动态的执行
		// initFreeList(buffernum);
		// 执行轮询的分配cmd资源到空闲的线程
		workQueue = new ArrayBlockingQueue<BaseCommandObject>(cmdQueueMaxCount);
		timerworkQueue = new PriorityBlockingQueue<BaseCommandObject>(cmdQueueMaxCount);
		freeQueue = new ArrayBlockingQueue<BaseCommandObject>(cmdQueueMaxCount);
		for (int i = 0; i < cmdQueueMaxCount; i++) {
			freeQueue.add(new BaseCommandObject());
		}
		dispatchProcessThread = new Thread("dispatchProcessThread") {
			@Override
			public void run() {
				dispatchProcess();
			}
		};
		runDispatchProcess = true;
		dispatchProcessThread.start();
		dispatchTimerProcessThread = new Thread("dispatchTimerProcessThread") {
			@Override
			public void run() {
				dispatchTimerProcess();
			}
		};
		dispatchTimerProcessThread.start();
		isInit = true;
		return true;
	}

	/** 暂停线程池轮询 */
	public void Pause() {
		isThreadPoolStated = false;
		dispatchStatus = ready_pause_status;
		pauseCmdThread();
	}

	/** 停止线程池,程序准备退出 */
	public void stop() {
		isThreadPoolStated = false;
		runDispatchProcess = false;
		stopCmdThread();
	}

	public void exitThread() {
		isThreadPoolStated = false;
		runDispatchProcess = false;
		stopCmdThread();
	}

	/**
	 * * 设线程为空闲,等待调度
	 * 
	 * @return
	 */
	/*private void runCmdThread() {
		if (cmdThreaLlist == null)
			return;
		for (int i = 0; i < cmdThreaLlist.size(); i++) {
			cmdThreaLlist.get(i).SetPauseReady();

		}
	}*/

	/**
	 * * 暂停线程
	 * 
	 * @return
	 */
	private void pauseCmdThread() {
		if (cmdThreaLlist == null)
			return;
		for (int i = 0; i < cmdThreaLlist.size(); i++) {
			cmdThreaLlist.get(i).SetPauseReady();

		}
	}

	/**
	 * * 此方法会让线程生命周期消失
	 * 
	 * @return
	 */
	private void stopCmdThread() {
		if (cmdThreaLlist == null)
			return;
		for (int i = 0; i < cmdThreaLlist.size(); i++) {
			cmdThreaLlist.get(i).setRun(false);

		}
	}

	/**
	 * 线程池初始化时候，初始化m个命令资源
	 * 
	 * @param buffernum
	 */
	/*
	 * private void initFreeList(int buffernum) { if (isinitFreeList) return;
	 * isinitFreeList = true; freeList = new
	 * ArrayList<BaseCommandObject>("ThreadPool_freeList", buffernum, false,
	 * false); useList = new ArrayList<BaseCommandObject>("ThreadPool_useList",
	 * buffernum, false, false); int count = 0; do { freeList.add(new
	 * CommandObject()); count++; } while (count < buffernum); }
	 */

	/**
	 * 线程池初始化时候，初始化m个专门负责执行命令的线程
	 * 
	 * @param threadnum
	 * @throws Throwable
	 */
	private void createthread(int threadnum) throws Throwable {
		// if (isCreateThread)
		// return;
		// isCreateThread = true;
		cmdThreaLlist = new ArrayList<CmdThread>("ThreadPool_cmdThreaLlist", threadnum, false, false);
		idleThreads = new ArrayBlockingQueue<CmdThread>(threadnum);
		// busyThreads=new ArrayBlockingQueue<CmdThread>(threadnum);
		int count = 0;
		do {
			CmdThread cmdThread = new CmdThread(count);
			cmdThreaLlist.add(cmdThread);
			// 初始化空闲队列
			idleThreads.add(cmdThread);
			cmdThread.start();
			count++;
		} while (count < threadnum);
	}

	public BaseCommandObject getFreeCommand() {
//		Log.debug("////使用command");
		return this.freeQueue.poll();
	}

	public BaseCommandObject takeFreeCommand(TimerCommand cmd) {
		if (cmd.command != null)
			return cmd.command;
//		Log.debug("////阻塞请求command");
		// BaseCommandObject command=null;
		try {
			cmd.command = this.freeQueue.take();
			// return this.freeQueue.take();
			return cmd.command;
		} catch (InterruptedException e) {
			e.printStackTrace();
			Log.error(e);
		} finally {
//			Log.debug("////阻塞返回command");
		}
		return null;
//		while (sessionMgr.command.getCmdstatus() != GameData.COMPLETECMD) {
//			try {
//				TimeUnit.MILLISECONDS.sleep(1);
//			} catch (InterruptedException e) {
//				e.printStackTrace();
//				break;
//			}
//		}
//		sessionMgr.command.setCmdstatus(GameData.RUNNINGCMD);
//		return sessionMgr.command;
	}

	public boolean freeUsedCommand(BaseCommandObject command) {
		if (command == null)
			return false;
//		Log.debug("////回收command");
		try {
			return this.freeQueue.add(command);// 如果回收不了就抛异常，因为所有使用command都是free里取的
		} catch (Exception e) {
			Log.error("freeQueue:" + freeQueue.size(), e);
			return false;
		}
	}

//	int targetCmdIn=0;
	public boolean Push(BaseCommandObject command) {
		if (command == null)
			return false;
		if (command instanceof TimerCommand) {
			command.start();
			return timerworkQueue.offer(command);
		}
//		if(command.getCmd()==2000){
//			targetCmdIn++;
//			Log.info("线程池push了请求房间列表次数"+targetCmdIn);
//		}
		return workQueue.offer(command);

	}

	/**
	 * 取消某个任务，如果不存在或执行完,返回false
	 * 
	 * @param command
	 * @return
	 */
	public boolean cancel(BaseCommandObject command) {
		if (command == null)
			return false;
		if (command instanceof TimerCommand) {
			return timerworkQueue.remove(command);
		}
		return workQueue.remove(command);

	}

	/**
	 * 将一个命令cmd，datapush到命令列表
	 * 
	 * @param sessionObject
	 * @param cmd
	 * @param data
	 * @return
	 * @throws Exception
	 */
	/*
	 * public boolean Push(SessionObject sessionObject, short cmd, byte[] data)
	 * throws Exception { if (!isThreadPoolStated) return false; if
	 * (freeList.size() <= 0) { throw new Exception("cmd list not enough "); }
	 * CommandObject temCommand = freeList.get(0);
	 * temCommand.setSessionObject(sessionObject); temCommand.setCmd(cmd);
	 * temCommand.setBytes(data); temCommand.setCmdstatus(INADDTOUSELIST);
	 * synchronized (freeList) { freeList.remove(temCommand); } synchronized
	 * (useList) { useList.add(temCommand); } return true; }
	 */

	/**
	 * 返回专门执行命令线程中一个空闲的线程 优化队列，建两个个固定长的队列
	 * 
	 * @return
	 */
	/*private CmdThread getIdleCmdThread() {
		for (int i = 0; i < cmdThreaLlist.size(); i++) {
			if (cmdThreaLlist.get(i).getCmdStatus() == idle_status)
				return cmdThreaLlist.get(i);
		}
		return null;
	}*/

	// MainProcess来处理命令列表，分配专门执行命令的空闲线程处理
	private void dispatchProcess() {
		Log.info("[线程池]委派任务开始");
		timeWatch.start();
		do {
			if (dispatchStatus == idle_status) {
				try {
					BaseCommandObject command = workQueue.poll(3, TimeUnit.SECONDS);
					if (command != null) {
						CmdThread cmdThread = idleThreads.take();// 一定要阻塞，否则命令出列了,没有处理
																	// getIdleCmdThread();
						if (cmdThread != null) {
							// 将当前命令的状态设置成正在在执行状态
							command.setCmdstatus(GameData.RUNNINGCMD);
							// 给执行命令的专门线程指定命令
							cmdThread.setRunFun(command);
						} else {
							Log.error("[线程池]没有取出空闲的线程处理命令！");
							throw new Error("[线程池]没有取出空闲的线程处理命令");
						}
					}
					TimeUnit.MILLISECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
					Log.info("[线程池]ThreadPool dispatchProcess InterruptedException!,跳出循环");
				}// 阻塞
			}
		} while (runDispatchProcess);
		timeWatch.stop(true, 0L);
		Log.info("[线程池]委派任务结束");
	}

	// MainProcess来处理命令列表，分配专门执行命令的空闲线程处理
	private void dispatchTimerProcess() {
		Log.info("[线程池]委派定时器任务开始");
		timerTimeWatch.start();
		do {
			if (dispatchStatus == idle_status) {
				try {
					// BaseCommandObject command = timerworkQueue.poll(3,
					// TimeUnit.SECONDS);
					BaseCommandObject command = timerworkQueue.peek();
					if (command != null) {
						if (command.runTime <= System.nanoTime()) {
							// Log.debug(String.format("%s执行%s runtime %s",
							// System.nanoTime(), command.name,
							// command.runTime));
							command = timerworkQueue.take();
//							Log.info("出栈:" + command);
							CmdThread cmdThread = idleThreads.take();// 一定要阻塞，否则命令出列了,没有处理
																		// //
																		// getIdleCmdThread();
							if (cmdThread != null) {
								// 将当前命令的状态设置成正在在执行状态
								command.setCmdstatus(GameData.RUNNINGCMD);
								// 给执行命令的专门线程指定命令
								cmdThread.setRunFun(command);
							} else {
								Log.error("[线程池]没有取出空闲的线程处理命令！");
								throw new Error("[线程池]没有取出空闲的线程处理命令");
							}
						}
					}
					TimeUnit.MILLISECONDS.sleep(1);

				} catch (InterruptedException e) {
					e.printStackTrace();
					Log.info("[线程池]ThreadPool dispatchProcess InterruptedException!,跳出循环");
				}// 阻塞
			}
		} while (runDispatchProcess);
		timerTimeWatch.stop(true, 0L);
		Log.info("[线程池]委派定时器任务结束");
	}

	// 比如20个线程执行所有的命令,idle，busy ,线程调用cmd对应的类的execute方法执行,传sessionObject ,

	// 执行完一个cmd，挂起，等待dispatcherThread唤醒
	// ThreadRun _threeelm[20];

	public boolean isThreadPoolStated() {
		return isThreadPoolStated;
	}

	// 线程池的状态，如果true，线程池会轮询命令列表，若为false,则跳出循环
	public void setThreadPoolStated(boolean isThreadPoolStated) {
		this.isThreadPoolStated = isThreadPoolStated;
	}

	public void printThreadPoolStatus() {
		if (!isThreadPoolStated && cmdThreaLlist == null)
			Log.info(String.format("[GameServer][%s] 线程池ThreadPool未启动!", DateUtil.format(new Date())));
		ConsoleTable t = new ConsoleTable(9, true);
		t.appendRow();
		t.appendColum("序号").appendColum("线程id").appendColum("状态").appendColum("执行命令数").appendColum("max run time").appendColum("max run cmdid").appendColum("min run time").appendColum("min run cmdid").appendColum("运行概况");
		int count = 0;
		int totalCmd = 0;
		int totalError = ThreadPool.ErrorCmdMap.size();
		CmdThread maxCmdThread = cmdThreaLlist.get(0);
		CmdThread minCmdThread = cmdThreaLlist.get(0);
		CmdThread cmdThread;
		int index;
		for (int i = 0; i < cmdThreaLlist.size(); i++) {
			cmdThread = cmdThreaLlist.get(i);
			index = 0;
			count++;
			totalCmd += cmdThread.getCmdCount();
			if (cmdThread.maxTime > maxCmdThread.maxTime) {
				maxCmdThread = cmdThread;
			}
			if (cmdThread.minTime > minCmdThread.minTime) {
				minCmdThread = cmdThread;
			}
//			totalError += cmdThread.exceptionCount;
			t.appendRow();
			t.appendColum(count).appendColum(cmdThread.getName()).appendColum(cmdThread.getThreadStatus()).appendColum(cmdThread.getCmdCount()).appendColum(cmdThread.getMaxTime()).appendColum(cmdThread.getMaxCmd()).appendColum(cmdThread.getMinTime()).appendColum(cmdThread.getMinCmd()).appendColum(cmdThread.statusList.toString());
		}
		t.appendRow();
		t.appendColum("work:timer:idleThreads").appendColum(this.workQueue.size() + ":" + timerworkQueue.size() + ":" + idleThreads.size()).appendColum("        ").appendColum(totalCmd).appendColum(maxCmdThread.maxTime).appendColum(String.format("%s %s", maxCmdThread.maxCmd, maxCmdThread.maxCmdName)).appendColum(maxCmdThread.minTime).appendColum(String.format("%s %s", maxCmdThread.minCmd, maxCmdThread.minCmdName)).appendColum("异常数:" + totalError);
		t.appendRow();
		t.appendColum("在线:").appendColum(GameData.ONLINECOUNT.get()).appendColum("userlist").appendColum(this.sessionMgr.getUseListSize()).appendColum("freeList:").appendColum(this.sessionMgr.getFreeListSize()).appendColum("UserMgr onlineUserList:").appendColum(UserMgr.I().onlineUserList.size());

		StringBuilder sb = new StringBuilder("\r\nTimes:");
//		for (Object obj : timerworkQueue) {
//			sb.append("[" + obj + "]");
//		}
		Iterator iter = ThreadPool.ErrorCmdMap.entrySet().iterator();
		while (iter.hasNext()) {
			Map.Entry entry = (Map.Entry) iter.next();
			sb.append(entry.getKey() + "<<cmd<<:" + entry.getValue());
		}
		Log.info(t.toString() + sb.toString());
	}

	public void printThreadPoolCurrentStatus() {
		Log.debug("==============ThreadPoolCurrentStatus=============");
		ConsoleTable t = new ConsoleTable(5, true);
		t.appendRow();
		t.appendColum("序号").appendColum("线程id").appendColum("isInterrupted").appendColum("isAlive").appendColum("isDaemon");
		int count = 0;
		CmdThread cmdThread;
		for (int i = 0; i < cmdThreaLlist.size(); i++) {
			cmdThread = cmdThreaLlist.get(i);
			count++;
			t.appendRow();
			t.appendColum(count).appendColum(cmdThread.getName()).appendColum(cmdThread.isInterrupted()).appendColum(cmdThread.isAlive()).appendColum(cmdThread.isDaemon());
		}
		Log.info(t.toString());
	}

	public void timersDetial() {
		try {
			Log.info("线程池定时器队列:" + timerworkQueue.toString());
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	// 执行命令的线程，根据实际应用在线程池里初始化相应的个数
	class CmdThread extends Thread {
		private boolean isRun;
		private final int index;
		private BaseCommandObject cmdObject;
		private short _status;
		private final TimeWatch timeWatch;
		private long maxTime = 0L;
		private long minTime = 0L;
		private short maxCmd = 0;
		private short minCmd = 0;
		private int cmdCount = 0;
		public String minCmdName = "";
		public String maxCmdName = "s";
//		public int exceptionCount;
		public StringBuilder statusList;

//		public ArrayList<Throwable> exceptions = new ArrayList<Throwable>();;

		public boolean isRun() {
			return isRun;
		}

		public void setRun(boolean isRun) {
			this.isRun = isRun;
		}

		public CmdThread(int _index) {
			super("CmdThread" + _index);
			index = _index;
			timeWatch = new TimeWatch("CmdThread" + index + " cmd操作:");
			isRun = true;
			_status = idle_status;
			statusList = new StringBuilder();
			// this.setDaemon(true);
		}

		public void setRunFun(BaseCommandObject _cmdObject) {
			this.cmdObject = _cmdObject;
			this.cmdObject.dbIndex = index;// 设置数据库索引
			SetRunReady();
		}

		/**
		 * 运行
		 */
		public void SetRunReady() {
			_status = ready_exec_status;
		}

		/**
		 * 暂停
		 */
		public void SetPauseReady() {
			_status = ready_pause_status;
		}

		public int getCmdStatus() {
			return _status;
		}

		/**
		 * 获取线程当前状态
		 * 
		 * @return
		 */
		public String getThreadStatus() {
			switch (_status) {
			case idle_status:
				return "空闲";
			case ready_exec_status:
				return "忙碌:" + this.cmdObject.getCmd();
			case ready_pause_status:
				return "暂停";
			default:
				return "未知";
			}
		}

		private void getComandFun() {
			// try {
			// 根据命令id得到一个执行命令的实例，并执行execute方法
			Command cmd = CommandSet.getCommand(this.cmdObject.getCmd());
			if (cmd != null) {
				// Log.warn(" Can not found cmdid= " +
				// this.cmdObject.getCmd());
				cmd.execute(this.cmdObject);
			}

			// } catch (Exception e) {exceptionCount++;
			// Log.info(String.format("[ThreadPool-Cmd][%s] 执行命令错误:%s!",
			// DateUtil.format(new Date()), e));
			// }
			// 将当前命令设置成执行完成，以便线程池能回收此资源,其实，此操作多余
			cmdObject.setCmdstatus(GameData.COMPLETECMD);
		}

		private void setMaxMinTime() {
			cmdCount++;
			if (cmdCount == 1) {
				this.setMaxTime(timeWatch.getSpendTime());
				this.setMinTime(timeWatch.getSpendTime());
				this.setMinCmd(this.cmdObject.getCmd());
				this.setMaxCmd(this.cmdObject.getCmd());
				minCmdName = this.cmdObject.name;
				maxCmdName = this.cmdObject.name;
			}
			if (timeWatch.getSpendTime() > this.getMaxTime()) {
				this.setMaxTime(timeWatch.getSpendTime());
				this.setMaxCmd(this.cmdObject.getCmd());
				maxCmdName = this.cmdObject.name;
			} else if (timeWatch.getSpendTime() < this.getMinTime()) {
				this.setMinTime(timeWatch.getSpendTime());
				this.setMinCmd(this.cmdObject.getCmd());
				minCmdName = this.cmdObject.name;
			}
		}

		@Override
		public void run() {
			while (isRun) {
				if (_status == ready_exec_status) {
					timeWatch.start();
					// 根据cmd，data，执行命令
					try {
						getComandFun();
					} catch (Exception e) {
						e.printStackTrace();
						ErrorCmdMap.put(cmdObject.getCmd(), e);
						Log.error(e);
					}

					// 执行完之后，此线程设置为空闲，以供TheadPool调度给新来的命令列表
					if (cmdObject instanceof TimerCommand) {
						timeWatch.stop(this.cmdObject.getCmd() + " " + ((TimerCommand) cmdObject).get("Type"), 2000L);// 如果超过2秒，警告
					} else {
						timeWatch.stop(this.cmdObject.getCmd() + " ", 2000L);// 如果超过2秒，警告
					}

					setMaxMinTime();
					timeWatch.reset();
					_status = idle_status;
					// 定时器任务
					if (cmdObject instanceof TimerCommand) {
						// Log.debug("已执行-->" + cmdObject.toString());
						if (!cmdObject.complete()) {
//							Log.info("任务继续入栈:" + cmdObject);
							timerworkQueue.put(cmdObject);// 没有执行完毕，归队
						} else {
							// Log.debug("已完毕-->" + cmdObject.toString());
							// ThreadPool.getInstance().freeUsedCommand(cmdObject);//??如果回收了，会被其他线程使用，timer设计成全局?
						}
						BaseCommandObject command = ((TimerCommand) cmdObject).command;
						if (command != null) {
							ThreadPool.getInstance().freeUsedCommand(command);
							((TimerCommand) cmdObject).command = null;
						}
					} else {
						ThreadPool.getInstance().freeUsedCommand(cmdObject);
					}
					// Log.debug("入队前size " + idleThreads.size());
					idleThreads.add(this);
				}
				try {
					TimeUnit.MILLISECONDS.sleep(1);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

		public int getCmdCount() {
			return cmdCount;
		}

		public void setCmdCount(int cmdCount) {
			this.cmdCount = cmdCount;
		}

		public long getMaxTime() {
			return maxTime;
		}

		public void setMaxTime(long maxTime) {
			this.maxTime = maxTime;
		}

		public long getMinTime() {
			return minTime;
		}

		public void setMinTime(long minTime) {
			this.minTime = minTime;
		}

		public short getMaxCmd() {
			return maxCmd;
		}

		public void setMaxCmd(short maxCmd) {
			this.maxCmd = maxCmd;
		}

		public short getMinCmd() {
			return minCmd;
		}

		public void setMinCmd(short minCmd) {
			this.minCmd = minCmd;
		}

	}
}
